package com.joysuch.wwyt.dynamicdata.processor;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.zlg.common.datadump.service.DataDumpService;
import com.google.common.collect.Maps;
import com.joysuch.wwyt.common.constant.Constant;
import com.joysuch.wwyt.core.common.util.SpringContextUtils;
import com.joysuch.wwyt.core.entity.BaseTypeGroupItem;
import com.joysuch.wwyt.core.service.BaseTypeGroupItemService;
import com.joysuch.wwyt.dynamicdata.DynamicDataConstants;
import com.joysuch.wwyt.dynamicdata.DynamicParam;
import com.joysuch.wwyt.dynamicdata.entity.BaseDynamicData;
import com.joysuch.wwyt.dynamicdata.entity.BaseDynamicFieldConfig;
import com.joysuch.wwyt.dynamicdata.entity.DictionaryDataSource;
import com.joysuch.wwyt.dynamicdata.enums.DataSourceTypeEnum;
import com.joysuch.wwyt.dynamicdata.service.BaseDynamicDataService;
import com.joysuch.wwyt.dynamicdata.service.BaseDynamicFieldConfigService;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class DynamicDataExportProcessor extends AbstractDynamicDataProcessor implements IDynamicDataProcessor {

    private final BaseDynamicDataService dynamicDataService;
    private final BaseTypeGroupItemService baseTypeGroupItemService;
    private final DataDumpService dataDumpService;
    private final BaseDynamicFieldConfigService dynamicFieldConfigService;

    public DynamicDataExportProcessor() {
        this.dynamicDataService = SpringContextUtils.getBean(BaseDynamicDataService.class);
        this.baseTypeGroupItemService = SpringContextUtils.getBean(BaseTypeGroupItemService.class);
        this.dataDumpService = SpringContextUtils.getBean(DataDumpService.class);
        this.dynamicFieldConfigService = SpringContextUtils.getBean(BaseDynamicFieldConfigService.class);
    }

    @Override
    public Object doProcess(DynamicParam param) {
        String dataDumpHandler = param.getDataDumpHandler();
        Object object = param.getTargetData();
        String dynamicDataBizType = dataDumpService.getDynamicDataBizType(dataDumpHandler);
        if (StringUtils.isNotBlank(dynamicDataBizType)) {
            List<BaseDynamicFieldConfig> fieldConfigList = dynamicFieldConfigService.findByBizType(dynamicDataBizType);
            //Map<TypeGroupId,Map<TypeGroupItemId,TypeGroupItemName>
            Map<Long, Map<Long, String>> typeGroupMap = buildGroupItemMap(fieldConfigList);
            Map<String, Long> fieldDataSourceMap = buildFieldNameGroupMap(fieldConfigList);
            if (object instanceof List<?>) {
                List<Object> objectList = new ArrayList<>();
                for (Object data : (List<?>) object) {
                    Object newObj = buildNewObject(data, typeGroupMap, fieldDataSourceMap);
                    objectList.add(newObj);
                }
                return objectList;
            } else {
                return buildNewObject(object, typeGroupMap, fieldDataSourceMap);
            }
        }
        return object;
    }

    private Object buildNewObject(Object object, Map<Long, Map<Long, String>> typeGroupMap, Map<String, Long> fieldDataSourceMap) {
        Map<String, Object> properties = Maps.newHashMap();
        JSONObject jsonObject = JSONUtil.parseObj(object);
        List<BaseDynamicData> dataList = dynamicDataService.findDataByBizId(Long.valueOf(jsonObject.get(DynamicDataConstants.ID).toString()));
        dataList.forEach(each -> {
            String fieldValue = each.getFieldValue();
            Long typeGroupId = fieldDataSourceMap.get(each.getFieldName());
            if (typeGroupId != null && typeGroupMap.containsKey(typeGroupId) && StringUtils.isNotBlank(fieldValue)) {
                fieldValue = typeGroupMap.get(typeGroupId).get(Long.valueOf(fieldValue));
            }
            properties.put(each.getFieldName(), fieldValue != null ? fieldValue : Constant.EMPTY_STR);
        });
        return addTargetField(object, properties);
    }

    private Map<String, Long> buildFieldNameGroupMap(List<BaseDynamicFieldConfig> fieldConfigList) {
        Map<String, Long> fieldDataSourceMap = new HashMap<>();
        fieldConfigList.forEach(each -> {
            String dataSourceStr = each.getDataSource();
            if (JSONUtil.isJsonObj(dataSourceStr)) {
                if (DataSourceTypeEnum.DICTIONARY.getValue().equals(each.getDataSourceType())) {
                    DictionaryDataSource dataSource = JSONUtil.toBean(dataSourceStr, DictionaryDataSource.class);
                    fieldDataSourceMap.put(each.getFieldName(), dataSource.getTypeGroupId());
                }
            }
        });
        return fieldDataSourceMap;
    }

    private Map<Long, Map<Long, String>> buildGroupItemMap(List<BaseDynamicFieldConfig> fieldConfigList) {
        Map<Long, Map<Long, String>> typeGroupMap = new HashMap<>();
        fieldConfigList.forEach(each -> {
            String dataSourceStr = each.getDataSource();
            if (JSONUtil.isJsonObj(dataSourceStr)) {
                if (DataSourceTypeEnum.DICTIONARY.getValue().equals(each.getDataSourceType())) {
                    DictionaryDataSource dataSource = JSONUtil.toBean(dataSourceStr, DictionaryDataSource.class);
                    if (!typeGroupMap.containsKey(dataSource.getTypeGroupId())) {
                        List<BaseTypeGroupItem> itemList = baseTypeGroupItemService.findByTypeGroupId(dataSource.getTypeGroupId());
                        //The current data volume of the data dictionary table is less than 300
                        Map<Long, String> groupItemMap = new HashMap<>(itemList.stream().collect(Collectors.toMap(BaseTypeGroupItem::getId, BaseTypeGroupItem::getName)));
                        typeGroupMap.put(dataSource.getTypeGroupId(), groupItemMap);
                    }
                }
            }
        });
        return typeGroupMap;
    }
}
